QuickOPC User's Guide and Reference
Type-less Mapping
Development Models > Live Mapping Model > Live Mapping Model for OPC Data (Classic and UA) > The Mapper Object > Type-less Mapping

While less common, you can actually using the live mapping mechanism for establishing a direct correspondence between mapping sources and mapping targets, without having to map the types. This may be beneficial e.g. if your application just needs to pick a small number of “scattered” items to be mapped from a large OPC address space, and at the same time you won’t gain much from defining the types for objects that exist in the OPC address space.

In order to use the type-less mapping, you need to call the DefineMapping method on the mapper object, passing it the three essential pieces of information: The mapping source, the mapping itself (not yet associated with the source and target), and the mapping target. The DefineMapping method associates the mapping with its source and target, and adds the mapping to the mapper.

The example below shows how to define a new type-less mapping which maps a specified OPC-DA item to the Value member of your target MyClass object. The mapper is then instructed to invoke the OPC read operation, which will in turn store the OPC item’s value to your target object.

// Instantiate the client mapper object.
var mapper = new DAClientMapper();

var target = new MyClass2();

// Define a type-less mapping.

mapper.DefineMapping(
     new DAClientItemSource("OPCLabs.KitServer.2", "Simulation.Register_I4", DADataSource.Cache),
     new DAClientItemMapping(typeof(Int32)),
     new ObjectMemberLinkingTarget(target.GetType(), target, "Value"));

// Perform a read operation.
mapper.Read();

Public Shared Sub Main1()
    Dim mapper = New DAClientMapper()
    Dim target = New MyClass2()

    ' Define a type-less mapping.

    mapper.DefineMapping( _
             New DAClientItemSource( _
                 "OPCLabs.KitServer.2",
                 "Simulation.Register_I4",
                 New DAReadParameters(DADataSource.Cache)),
             New DAClientItemMapping(GetType(Int32)),
             New ObjectMemberLinkingTarget(target.GetType(), target, "Value"))

    ' Perform a read operation.
    mapper.Read()

    ' Display the result.
    Console.WriteLine(target.Value)
End Sub

 

 

The example below shows how to define a new type-less mapping which maps a specified node in OPC Unified Architecture (OPC-UA) server to the Value member of your target MyClass2 object. The mapper is then instructed to invoke the OPC read operation, which will in turn store the OPC node’s value to your target object:

UAEndpointDescriptor endpointDescriptor =
    "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer";
// or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
// or "https://opcua.demo-this.com:51212/UA/SampleServer/"

var mapper = new UAClientMapper();
var target = new MyClass2();

// Define a type-less mapping.

MemberInfo memberInfo = target.GetType().GetMember("Value").SingleOrDefault();
Debug.Assert(memberInfo != null);

mapper.DefineMapping(
    new UAClientDataMappingSource(
        endpointDescriptor,
        "nsu=http://test.org/UA/Data/ ;i=10389",
        UAAttributeId.Value,
        UAIndexRangeList.Empty,
        UAReadParameters.CacheMaximumAge),
    new UAClientDataMapping(typeof(Int32)),
    new ObjectMemberLinkingTarget(target.GetType(), target, memberInfo));

// Perform a read operation.
mapper.Read();

Public Shared Sub Main1()

    ' Define which server we will work with.
    Dim endpointDescriptor As UAEndpointDescriptor =
            "opc.tcp://opcua.demo-this.com:51210/UA/SampleServer"
    ' or "http://opcua.demo-this.com:51211/UA/SampleServer" (currently not supported)
    ' or "https://opcua.demo-this.com:51212/UA/SampleServer/"

    Dim mapper = New UAClientMapper()
    Dim target = New MyClass2()

    ' Define a type-less mapping.

    Dim memberInfo = target.GetType().GetMember("Value").SingleOrDefault()
    Debug.Assert(memberInfo IsNot Nothing)

    mapper.DefineMapping( _
        New UAClientDataMappingSource( _
            endpointDescriptor, _
            "nsu=http://test.org/UA/Data/ ;i=10389", _
            UAAttributeId.Value, _
            UAIndexRangeList.Empty, _
            UAReadParameters.CacheMaximumAge), _
        New UAClientDataMapping(GetType(Int32)), _
        New ObjectMemberLinkingTarget(target.GetType(), target, memberInfo))

    ' Perform a read operation.
    mapper.Read()

    ' Display results
    Console.WriteLine(target.Value)
End Sub

 

 

In order to remove the mapping added in this way, call the UndefineMapping method on the mapper object.

 

The example below shows how to subscribe and unsubscribe:

// This example for OPC DA type-less mapping shows how to define a mapping and perform subscribe and unsubscribe operations.

using System;
using System.Threading;
using OpcLabs.BaseLib.ComponentModel.Linking;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.LiveMapping;

namespace DocExamples.DataAccess._DAClientMapper
{
    partial class DefineMapping
    {
        class MyClassSubscribe
        {
            public Double Value
            {
                set
                {
                    // Display the incoming value
                    Console.WriteLine(value);
                }
            }
        }

        public static void Subscribe()
        {
            // Instantiate the client mapper object.
            var mapper = new DAClientMapper();

            var target = new MyClassSubscribe();

            // Define a type-less mapping.

            mapper.DefineMapping(
                 new DAClientItemSource("OPCLabs.KitServer.2", "Demo.Ramp", 1000, DADataSource.Cache),
                 new DAClientItemMapping(typeof(Double)),
                 new ObjectMemberLinkingTarget(target.GetType(), target, "Value"));

            // Perform a subscribe operation.
            mapper.Subscribe(true);

            Thread.Sleep(30 * 1000);

            // Perform an unsubscribe operation.
            mapper.Subscribe(false);
        }
    }
}

' This example for OPC DA type-less mapping shows how to define a mapping and perform subscribe and unsubscribe operations.

Imports OpcLabs.BaseLib.ComponentModel.Linking
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.LiveMapping

Namespace _DAClientMapper
    Partial Friend Class DefineMapping
        Class MyClassSubscribe
            Public WriteOnly Property Value As Double
                Set(value As Double)
                    ' Display the incoming value
                    Console.WriteLine(value)
                End Set
            End Property
        End Class

        Public Shared Sub Subscribe()
            Dim mapper = New DAClientMapper()
            Dim target = New MyClassSubscribe()

            ' Define a type-less mapping.

            mapper.DefineMapping(
                 New DAClientItemSource("OPCLabs.KitServer.2", "Demo.Ramp", 1000, DADataSource.Cache),
                 New DAClientItemMapping(GetType(Double)),
                 New ObjectMemberLinkingTarget(target.GetType(), target, "Value"))

            ' Perform a subscribe operation.
            mapper.Subscribe(True)

            Threading.Thread.Sleep(30 * 1000)

            ' Perform an unsubscribe operation.
            mapper.Subscribe(False)
        End Sub
    End Class
End Namespace

 

 

The example below shows how to make various kinds of mappings:

// This example for OPC DA type-less mapping shows how to define mappings of various kinds, and perform subscribe and 
// unsubscribe operations.

using System;
using System.Threading;
using OpcLabs.BaseLib.ComponentModel.Linking;
using OpcLabs.EasyOpc.DataAccess;
using OpcLabs.EasyOpc.DataAccess.Generic;
using OpcLabs.EasyOpc.DataAccess.LiveMapping;

namespace DocExamples.DataAccess._DAClientMapper
{
    partial class DefineMapping
    {
        class MyClassMappingKinds
        {
            public Double CurrentValue
            {
                set
                {
                    // Display the incoming value
                    Console.WriteLine("Value: {0}", value);
                }
            }

            public DAVtq<Double> CurrentVtq
            {
                set
                {
                    // Display the incoming Vtq
                    Console.WriteLine("Vtq: {0}", value);
                }
            }

            public Exception CurrentException
            {
                set
                {
                    // Display the incoming exception
                    Console.WriteLine("Exception: {0}", value);
                }
            }

            public DAVtqResult<Double> CurrentResult
            {
                set
                {
                    // Display the incoming result
                    Console.WriteLine("Result: {0}", value);
                }
            }
        }

        public static void MappingKinds()
        {
            // Instantiate the client mapper object.
            var mapper = new DAClientMapper();

            var target = new MyClassMappingKinds();

            // Define several type-less mappings for the same source, with different mapping kinds.

            Type targetType = target.GetType();
            var source = new DAClientItemSource("OPCLabs.KitServer.2", "Demo.Ramp", 1000, DADataSource.Cache);

            mapper.DefineMapping(
                 source,
                 new DAClientItemMapping(typeof(Double)),
                 new ObjectMemberLinkingTarget(targetType, target, "CurrentValue"));

            mapper.DefineMapping(
                 source,
                 new DAClientItemMapping(typeof(Double), DAItemMappingKind.Vtq),
                 new ObjectMemberLinkingTarget(targetType, target, "CurrentVtq"));

            mapper.DefineMapping(
                 source,
                 new DAClientItemMapping(typeof(Double), DAItemMappingKind.Exception),
                 new ObjectMemberLinkingTarget(targetType, target, "CurrentException"));

            mapper.DefineMapping(
                 source,
                 new DAClientItemMapping(typeof(Double), DAItemMappingKind.Result),
                 new ObjectMemberLinkingTarget(targetType, target, "CurrentResult"));

            // Perform a subscribe operation.
            mapper.Subscribe(true);

            Thread.Sleep(30 * 1000);

            // Perform an unsubscribe operation.
            mapper.Subscribe(false);
        }
    }
}

' This example for OPC DA type-less mapping shows how to define mappings of various kinds, and perform subscribe and 
' unsubscribe operations.

Imports OpcLabs.BaseLib.ComponentModel.Linking
Imports OpcLabs.EasyOpc.DataAccess
Imports OpcLabs.EasyOpc.DataAccess.Generic
Imports OpcLabs.EasyOpc.DataAccess.LiveMapping

Namespace _DAClientMapper
    Partial Friend Class DefineMapping
        Class MyClassMappingKinds
            Public WriteOnly Property CurrentValue As Double
                Set(value As Double)
                    ' Display the incoming value
                    Console.WriteLine("Value: {0}", value)
                End Set
            End Property

            Public WriteOnly Property CurrentVtq As DAVtq(Of Double)
                Set(value As DAVtq(Of Double))
                    ' Display the incoming Vtq
                    Console.WriteLine("Vtq: {0}", value)
                End Set
            End Property

            Public WriteOnly Property CurrentException As Exception
                Set(value As Exception)
                    ' Display the incoming exception
                    Console.WriteLine("Exception: {0}", value)
                End Set
            End Property

            Public WriteOnly Property CurrentResult As DAVtqResult(Of Double)
                Set(value As DAVtqResult(Of Double))
                    ' Display the incoming result
                    Console.WriteLine("Result: {0}", value)
                End Set
            End Property
        End Class

        Public Shared Sub MappingKinds()
            Dim mapper = New DAClientMapper()
            Dim target = New MyClassMappingKinds()

            ' Define several type-less mappings for the same source, with different mapping kinds.

            Dim targetType = target.GetType()
            Dim source = New DAClientItemSource("OPCLabs.KitServer.2", "Demo.Ramp", 1000, DADataSource.Cache)

            mapper.DefineMapping(
                 source,
                 New DAClientItemMapping(GetType(Double)),
                 New ObjectMemberLinkingTarget(targetType, target, "CurrentValue"))

            mapper.DefineMapping(
                 source,
                 New DAClientItemMapping(GetType(Double), DAItemMappingKind.Vtq),
                 New ObjectMemberLinkingTarget(targetType, target, "CurrentVtq"))

            mapper.DefineMapping(
                 source,
                 New DAClientItemMapping(GetType(Double), DAItemMappingKind.Exception),
                 New ObjectMemberLinkingTarget(targetType, target, "CurrentException"))

            mapper.DefineMapping(
                 source,
                 New DAClientItemMapping(GetType(Double), DAItemMappingKind.Result),
                 New ObjectMemberLinkingTarget(targetType, target, "CurrentResult"))

            ' Perform a subscribe operation.
            mapper.Subscribe(True)

            Threading.Thread.Sleep(30 * 1000)

            ' Perform an unsubscribe operation.
            mapper.Subscribe(False)
        End Sub
    End Class
End Namespace

 

 

See Also